#define	DCFANDRV_C	

#include "DCFanDrv.h"

#define FAN_FILTER_TIME         (60000000u/FAN_MAX_SPEED/PLUSE_PER_CYCLE)      // 风速反馈滤波时间，单位us.
#define CAL_CYCLE				(PLUSE_PER_CYCLE*CAL_PER_TURN)
 
typedef struct _TYPE_DC_FAN
{
	unsigned short	u16_aimSpeed;
	unsigned short	u16_curSpeed;
	unsigned char	u8_timeCnt;
	unsigned char	u8_errCnt;
	unsigned char	u8_pulseCnt;
	unsigned char	u8_adjTime;
	unsigned long	u32_lastTimer;
	unsigned long	u32_speedTime;
	unsigned short	u16_duty;
}TYPE_DC_FAN;

TYPE_DC_FAN  InFan = {0};

/**************************************************************
//Fuction Name: void SetFanDuty(unsigned short u16_duty)
//Desrition: 占空比设置
//Input: 
//Output: 	
//Author:Chen Shou Min
//Date:2021.12.1
***************************************************************/
void SetFanDuty(unsigned short u16_duty)
{
	static unsigned char u8_lastDuty = 0;

	if(u8_lastDuty != u16_duty)
	{
		if(0 == u16_duty)
		{
			StopFanPwm();
		}
		else if(0 == u8_lastDuty)
		{
			if(u16_duty > MAX_PWM_DUTY)u16_duty = MAX_PWM_DUTY;
			if(u16_duty < MIN_PWM_DUTY)u16_duty = MIN_PWM_DUTY;
			StarFanPwm(u16_duty);
		}
		else
		{
			if(u16_duty > MAX_PWM_DUTY)u16_duty = MAX_PWM_DUTY;
			if(u16_duty < MIN_PWM_DUTY)u16_duty = MIN_PWM_DUTY;
			ChangeFanPwm(u16_duty);          
		}
		u8_lastDuty = u16_duty;
	}
}

/**************************************************************
//Fuction Name: PWMAdjust(void)
//Desrition: PWM占空比调节
//Input: 
//Output: 
//Author:Chen Shou Min
//Date:2021.12.1
***************************************************************/
void PWMAdjust(void)
{
	int temp = 0;
	
	if(InFan.u16_aimSpeed == 0)
	{
		InFan.u16_duty = 0;
		InFan.u8_adjTime = 0;
	}
	else
	{
		if(GetTimeTick(TIME_10ms))
		{
			if(InFan.u8_adjTime)InFan.u8_adjTime --;
		}
		if(InFan.u8_adjTime == 0)
		{
			InFan.u8_adjTime = 40;// 调节间隔时间最低400ms
			temp = InFan.u16_aimSpeed - InFan.u16_curSpeed;
			if((temp > 5)||(temp < -5))
			{
				temp = temp / 5;
				if(temp > MAX_ADJ_VAL)temp = MAX_ADJ_VAL;
				else if(temp < (-MAX_ADJ_VAL))temp = (-MAX_ADJ_VAL);
				InFan.u16_duty += temp;
				if(InFan.u16_duty > MAX_PWM_DUTY)InFan.u16_duty = MAX_PWM_DUTY;
				else if(InFan.u16_duty < MIN_PWM_DUTY)InFan.u16_duty = MIN_PWM_DUTY;
			}	
		}
	}
	SetFanDuty(InFan.u16_duty);
}

/**************************************************************
//Fuction Name: void InFanBckIRQ(void)
//Desrition: 直流风机反馈中断函数
//Input: 
//Output: 
//Author:Chen Shou Min
//Date:2021.12.1
***************************************************************/
void InFanBckIRQ(void)
{
	static unsigned long u32_tmpCnt = 0;
	static unsigned long u32_lastCnt = 0;
	
	u32_tmpCnt	= GetFreeTimer();// 单位：us
	if((u32_tmpCnt - u32_lastCnt >= FAN_FILTER_TIME)
	&&(0 == GetFanFBPin()))
	{
		u32_lastCnt = u32_tmpCnt;
		if(0 == InFan.u8_timeCnt)
		{
			InFan.u8_pulseCnt = 0;
			InFan.u32_lastTimer = u32_tmpCnt;
		}
		else
		{
			InFan.u8_pulseCnt ++;
			if(InFan.u8_pulseCnt >= CAL_CYCLE)
			{
				InFan.u8_pulseCnt = 0;
				if(0 == InFan.u32_speedTime)
				{
					InFan.u32_speedTime = u32_tmpCnt - InFan.u32_lastTimer;
				}
				InFan.u32_lastTimer = u32_tmpCnt;
			}
		}
		InFan.u8_timeCnt = 100;
	}
}


/**************************************************************
//Fuction Name: void GetCurFan(void)
//Desrition: 检测转速函数
//Input: 
//Output: 
//Author:Chen Shou Min
//Date:2021.12.1
***************************************************************/
void GetCurFan(void)
{
	if(GetTimeTick(TIME_10ms))
	{
		if(InFan.u8_timeCnt)
		{
			InFan.u8_timeCnt --;
			if(InFan.u8_timeCnt == 0)
			{// 检测风机反馈脉冲超时，转速为0
				InFan.u8_pulseCnt = 0;
				InFan.u16_curSpeed = 0;
				InFan.u32_speedTime = 0;
			}
		}
	}
	
	if(InFan.u8_timeCnt)
	{
		if(InFan.u32_speedTime)
		{
			InFan.u16_curSpeed = (unsigned short)((60000000u*CAL_PER_TURN)/InFan.u32_speedTime);
			InFan.u32_speedTime = 0;
			InFan.u8_adjTime = 0;
		}
	}
}

/**************************************************************
//Fuction Name: void GetCurFan(void)
//Desrition: 检测转速函数
//Input: 
//Output: 
//Author:Chen Shou Min
//Date:2021.12.1
***************************************************************/
void FanCheckError(void)
{
	if((InFan.u16_aimSpeed)
	&&(InFan.u16_curSpeed < FAN_MIN_SPEED))
	{
		if(GetTimeTick(TIME_1s))
		{
			if(InFan.u8_errCnt < 0xff)InFan.u8_errCnt ++;
		}
	}
	else
	{
		InFan.u8_errCnt = 0;
	}
}

/**************************************************************
//Fuction Name: FanDrvProc(void)
//Desrition: 风机主函数
//Input: 
//Output: 
//Author:Chen Shou Min
//Date:2021.12.1
***************************************************************/
void FanDrvProc(void)
{
	static unsigned char IniIs = 0;
	if(IniIs == 0)
	{	
		IniIs = 1;
		FanDrvInit();
	}
	GetCurFan();
	PWMAdjust();
	FanCheckError();
}

/**************************************************************
//Fuction Name: void SetInFanSpeed(unsigned short Speed)
//Desrition: 设置目标转速
//Input: 		目标转速
//Output: 
//Author:Chen Shou Min
//Date:2021.12.1
***************************************************************/
void SetInFanSpeed(unsigned short Speed)
{
	InFan.u16_aimSpeed = Speed;
}

/**************************************************************
//Fuction Name: unsigned short GetCurFanSpeed(void)
//Desrition: 获取当前转速
//Input: 		
//Output: 当前转速
//Author:Chen Shou Min
//Date:2021.12.1
***************************************************************/
unsigned short GetCurFanSpeed(void)
{
	return InFan.u16_curSpeed;
}

/**************************************************************
//Fuction Name: unsigned short GetCurFanSpeed(void)
//Desrition: 获取风机错误
//Input: 		
//Output: 风机错误计数
//Author:Chen Shou Min
//Date:2021.12.1
***************************************************************/
unsigned char GetFanErrCnt(void)
{
	return InFan.u8_errCnt;
}
